package com.jzo2o.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.enums.EnableStatusEnum;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.customer.enums.CertificationStatusEnum;
import com.jzo2o.customer.mapper.AgencyCertificationAuditMapper;
import com.jzo2o.customer.model.domain.AgencyCertification;
import com.jzo2o.customer.model.domain.AgencyCertificationAudit;
import com.jzo2o.customer.model.dto.AgencyCertificationUpdateDTO;
import com.jzo2o.customer.model.dto.request.AgencyCertificationAuditAddReqDTO;
import com.jzo2o.customer.model.dto.request.AgencyCertificationAuditPageQueryReqDTO;
import com.jzo2o.customer.model.dto.request.CertificationAuditReqDTO;
import com.jzo2o.customer.model.dto.response.AgencyCertificationAuditResDTO;
import com.jzo2o.customer.model.dto.response.RejectReasonResDTO;
import com.jzo2o.customer.service.IAgencyCertificationAuditService;
import com.jzo2o.customer.service.IAgencyCertificationService;
import com.jzo2o.customer.service.IServeProviderService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @Author: wen
 * @Time: 2024-04-26 15:48
 * @Version: 1.0
 */
@Service
public class AgencyCertificationAuditServiceImpl extends ServiceImpl<AgencyCertificationAuditMapper, AgencyCertificationAudit> implements IAgencyCertificationAuditService {

    @Resource
    private IAgencyCertificationService agencyCertificationService;

    @Resource
    private IServeProviderService serveProviderService;

    /**
     * 机构申请资质认证
     *
     * @param dto 认证申请请求体
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyCertification(AgencyCertificationAuditAddReqDTO dto) {
        //1.新增申请资质认证记录
        AgencyCertificationAudit agencyCertificationAudit = BeanUtil.toBean(dto, AgencyCertificationAudit.class);
        baseMapper.insert(agencyCertificationAudit);
        //查询认证记录
        Long serveProviderId = dto.getServeProviderId();
        AgencyCertification agencyCertification = agencyCertificationService.getById(serveProviderId);

        if (ObjectUtil.isNotNull(agencyCertification)) {
            //2.将认证信息状态更新为认证中
            agencyCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            agencyCertificationService.updateById(agencyCertification);
        } else {
            agencyCertification = new AgencyCertification();
            agencyCertification.setId(serveProviderId);
            agencyCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            agencyCertificationService.save(agencyCertification);
        }
    }

    /**
     * 审核认证信息
     *
     * @param id  申请记录id
     * @param dto 审核请求
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditCertification(Long id, CertificationAuditReqDTO dto) {
        //1.更新申请记录
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        LambdaUpdateWrapper<AgencyCertificationAudit> updateWrapper = Wrappers.<AgencyCertificationAudit>lambdaUpdate()
                .eq(AgencyCertificationAudit::getId, id)
                .set(AgencyCertificationAudit::getAuditStatus, EnableStatusEnum.ENABLE.getStatus())
                .set(AgencyCertificationAudit::getAuditorId, currentUserInfo.getId())
                .set(AgencyCertificationAudit::getAuditorName, currentUserInfo.getName())
                .set(AgencyCertificationAudit::getAuditTime, LocalDateTime.now())
                .set(AgencyCertificationAudit::getCertificationStatus, dto.getCertificationStatus())
                .set(ObjectUtil.isNotEmpty(dto.getRejectReason()), AgencyCertificationAudit::getRejectReason, dto.getRejectReason());
        super.update(updateWrapper);

        //2.更新认证信息，如果认证成功，需要将各认证属性也更新
        AgencyCertificationAudit audit = baseMapper.selectById(id);
        AgencyCertificationUpdateDTO updateDTO = new AgencyCertificationUpdateDTO();
        updateDTO.setId(audit.getServeProviderId());
        updateDTO.setCertificationStatus(dto.getCertificationStatus());
        if (ObjectUtil.equal(CertificationStatusEnum.SUCCESS.getStatus(), dto.getCertificationStatus())) {
            //如果认证成功，需要更新服务人员/机构名称
            serveProviderService.updateNameById(audit.getServeProviderId(), audit.getName());

            updateDTO.setName(audit.getName());
            updateDTO.setIdNumber(audit.getIdNumber());
            updateDTO.setLegalPersonName(audit.getLegalPersonName());
            updateDTO.setLegalPersonIdCardNo(audit.getLegalPersonIdCardNo());
            updateDTO.setBusinessLicense(audit.getBusinessLicense());
            updateDTO.setCertificationTime(audit.getAuditTime());
        }
        agencyCertificationService.updateByServeProviderId(updateDTO);
    }

    /**
     * 分页查询
     *
     * @param dto 分页查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<AgencyCertificationAuditResDTO> pageQuery(AgencyCertificationAuditPageQueryReqDTO dto) {
        Page<AgencyCertificationAudit> page = PageUtils.parsePageQuery(dto, AgencyCertificationAudit.class);
        LambdaQueryWrapper<AgencyCertificationAudit> queryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                // 查询条件
                .like(ObjectUtil.isNotEmpty(dto.getName()), AgencyCertificationAudit::getName, dto.getName())
                .like(ObjectUtil.isNotEmpty(dto.getLegalPersonName()), AgencyCertificationAudit::getLegalPersonName, dto.getLegalPersonName())
                .eq(ObjectUtil.isNotEmpty(dto.getAuditStatus()), AgencyCertificationAudit::getAuditStatus, dto.getAuditStatus())
                .eq(ObjectUtil.isNotEmpty(dto.getCertificationStatus()), AgencyCertificationAudit::getCertificationStatus, dto.getCertificationStatus());
        Page<AgencyCertificationAudit> result = baseMapper.selectPage(page, queryWrapper);
        return PageUtils.toPage(result, AgencyCertificationAuditResDTO.class);
    }

    /**
     * 查询当前用户最近的驳回原因
     * <p>
     * 该方法不接受任何参数，而是通过查询数据库来获取当前用户的最近一次驳回原因。
     * 查询条件基于当前用户的用户ID，查询结果按创建时间降序排列，并仅返回第一个（即最近的）记录。
     *
     * @return RejectReasonResDTO 包含最近驳回原因的数据传输对象
     */
    @Override
    public RejectReasonResDTO queryCurrentUserLastRejectReason() {
        // 构造查询条件，查询当前用户ID的最近一次认证审核记录
        LambdaQueryWrapper<AgencyCertificationAudit> queryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                .eq(AgencyCertificationAudit::getServeProviderId, UserContext.currentUserId())
                .orderByDesc(AgencyCertificationAudit::getCreateTime)
                .last("limit 1");
        // 执行查询，并获取最近的一条记录
        AgencyCertificationAudit agencyCertificationAudit = baseMapper.selectOne(queryWrapper);
        // 将查询结果包装成RejectReasonResDTO并返回
        return new RejectReasonResDTO(agencyCertificationAudit.getRejectReason());
    }

}
